home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1994 January / PSL Monthly Shareware CD-ROM (Public Software Library) (January 1994).iso / games / dos / arcade / brix.exe / INFO.TXT < prev    next >
Encoding:
Text File  |  1991-12-15  |  16.8 KB  |  336 lines

  1. ViewPoint(TM)
  2. -------------
  3.  
  4. Howdy.  I hate stupid ads.  I think marketing hype and stuff that looks like
  5. it belongs on a cerial box belong in this category.  So this is not an ad
  6. in the usual sence of the word.  I'll stay away from hype and slogans and
  7. just tell you about the library, programmer to programmer.
  8.  
  9. First some basics:  the "C++ ViewPoint Graphics Library -- Essential
  10. Drawing Components" is a rendering library for PC's.  It is easy to use,
  11. powerful, and fast.
  12.  
  13. -------------------------------
  14.  
  15. I interrupt this prose to bring you an example, to show the overall
  16. flavor of the library.  Here is a graphical equivilent of a "hello world"
  17. program-- one that shows you can compile and link and do something simple.
  18. This draws a square with an X in the middle, centered in the screen.  It
  19. is mostly housekeeping and overhead, since the program itself does not
  20. do much.
  21.  
  22.  
  23.       #include "usual.h"
  24.       #include "vp.h"
  25.       #include "device.h"
  26.       #include "getkey.h"
  27.       
  28.       screen_device d ("vga.drv");
  29.  
  30.       int main()
  31.       {
  32.       if (!d.init()) return 3;  //go into graphics mode
  33.       viewport v (d);  //the whole screen
  34.       v.set_scale (0,0,999,999);
  35.       v.rectangle (333,333, 666,666);
  36.       v.line (400,400, 600,600);
  37.       v.line (400,600, 600,400);
  38.       key::get();  //pause
  39.       }
  40.  
  41.  
  42. First, look at the include files.  USUAL.H is included in every source
  43. file.  VP.H is included for the viewport class, and DEVICE.H is
  44. included for the device class and its derived type, the screen_device.
  45. The last include file, GETKEY.H, is to supply the key class used
  46. in the example to pause and wait for a keypress.
  47.  
  48. The next line defines `d', a screen_device.  The screen device is a
  49. shell around loadable device drivers, and the constructor will load the
  50. named driver.  
  51.                                    
  52. The first line in main() is a call to device::init() which will activate
  53. the driver.  A parameter can be given to specify which mode to  use, as a
  54. driver may support a number of different graphics modes.  In this case
  55. no parameter is used so it will take the default as recorded in the
  56. driver file itself.  It returns FALSE if not successful.
  57.  
  58. After calling init(), `d' is an active device, and any rendering primitives
  59. (member functions of class device) can be used on it.  However, these drawing
  60. functions really are quite primitive, and they use absolute device pixels.
  61.  
  62. Depending on which driver you used, the number of pixels on the screen can
  63. vary.  So drawing a rectangle in the center will require some calculation.
  64. You can find out what the resolution of the display is with d.xmax()
  65. and d.ymax(), and use some computations in every point you plot to
  66. adjust it to the actual display size.  That is quite a pain.
  67.  
  68. So the library offers "world coordinates" which is basically a way to have
  69. the library do all that calculation for you.  The viewport is a higher
  70. level class which has this ability.
  71.  
  72. A viewport is attached to some device.  Line 11 defines `v' to be a
  73. viewport attached to `d' and taking up the whole screen.  Now you can
  74. use the high level commands in v instead of the low level commands in d,
  75. but the scaling problem still remains-- the pixels in v are exactly the
  76. same as those in d.
  77.  
  78. The next line solves this.  Instead of having to adapt my code to deal
  79. with whatever display resolution is at run time, I turn it around and tell
  80. it what size coordinate system I want to use.  The call to v.set_scale()
  81. specifies what I want to call the upper left and lower right pixels in the
  82. viewport.  Now, all uses of v will use the resolution I specified,
  83. automatically mapping it to the physical device.
  84.  
  85. The next line draws a rectangle, centered in the 1000x1000 viewport.
  86. The following draw the diagonal lines to form the X.  The last
  87. waits for a keypress.
  88.  
  89. Note that there is no code for cleaning up.  When v goes out of scope, the
  90. viewport is destroyed.  When d goes out of scope (at program termination)
  91. its destructor will put the screen back in text mode, as if d.finish()
  92. was called.
  93.  
  94. -------------------------------
  95.  
  96. The 17 line example above should give you some idea of how it is set up.
  97. There is a low level device class and a high level viewport class.
  98.  
  99. The device class offers primitive commands.  There are command for reading
  100. device information (like what the resolution is), color and palette
  101. control, display control, and rendering.
  102.  
  103. The color commands can deal with 32 bit color.  Many other libraries are
  104. locked into 8 bit pixels.  But the future of PC graphics offers more
  105. advanced abilities than this.  Since 32 bit numbers are less efficient
  106. to manipulate, the library can be compiled to deal with 8, 16 or 32
  107. bit values (16 is the default).  Code compiled with one option can be
  108. linked with code compiled with another setting.  With ViewPoint, you can
  109. use advanced features like the Siearra Hi-Color DAC with 32768 colors.
  110. Color may be mapped, and there are functions to set up the palette.
  111. The palette control will do the best it can for the device in use.  The
  112. BGI, for example, uses different commands for EGA and VGA color settings!
  113. The VP's device class is intended to abstract the device, so this one
  114. function will set palette mapping in the best way for whatever device.
  115.  
  116. The rendering functions include pixels, lines, rectangles, flood filling,
  117. and block moves.  They are all pretty simple, like read_pixel(x,y) or
  118. line (style, x1,y1,x2,y2).  You would find using functions on this level
  119. to be very much like using other graphics libraries.
  120.  
  121. But you normally don't use the device rendering functions.  Rather, you
  122. use the viewport rendering functions, which are themselves implemented
  123. using the device's.
  124.  
  125. A viewport is a higher level entity than an device.  It belongs to some
  126. device, so drawing with the viewport will make stuff appear on that
  127. device.  It also holds a style and a coordinate system.
  128.  
  129. All the device rendering commands take a style as the first parameter.
  130. The viewport holds a style and implies this style, so you don't specify
  131. it each time.
  132.  
  133. A viewport does coordinate transformations.  Rather than plotting in
  134. device pixels, you can use any kind of coordinate system you like.  The
  135. program above could pretend that the screen was 1000x1000 and use
  136. constants for all its positions, even though this program will run on
  137. any kind of device at all.  That is a simple example.  Coordinate
  138. systems can be rotated and skewed.  See the SEGMENT demo program.
  139.  
  140. The viewport also has more drawing functions, and they are friendlier.
  141. While a device has 
  142.    void device::line (const gfxstyle&, int x1,int y1, int x2,int y2);
  143. A viewport has
  144.    // absolute
  145.    viewport& line (int x1,int y1, int x2,int y2);
  146.    viewport& line (const pair& p1, const pair& p2);
  147.    viewport& line (const rect& r);
  148.    viewport& line (int x, int y);
  149.    viewport& line (const pair& p2);
  150.    viewport& movecp (int x1, int y1);
  151.    viewport& movecp (const pair& p);
  152.    // relative
  153.    viewport& line_rel (int deltax, int deltay);
  154.    viewport& line_rel (const pair& delta);
  155.    viewport& up (int dist);
  156.    viewport& down (int dist);
  157.    viewport& left (int dist);
  158.    viewport& right (int dist);
  159.    viewport& movecp_rel (int deltax, int deltay);
  160.    viewport& movecp_rel (const pair& p);
  161.    // polylines
  162.    viewport& polyline (int count, const int* data);  //absolute
  163.    viewport& polyline (int count, const pair* data);  //absolute
  164.    viewport& polyline_rel (int count, const int* data, int x, int y);
  165.    viewport& polyline_rel (int count, const int* data, const pair& start);
  166.    viewport& polyline_rel (int count, const pair* data, int x, int y);
  167.    viewport& polyline_rel (int count, const pair* data, const pair& start);
  168.  
  169. Of these 21 functions, 5 of them are called `line'.  Thanks to overloading
  170. in C++, the library can be easier to use.  It is quite practical to have
  171. 5 different line functions since you don't have to remember 5 different
  172. names.  You just give it whatever kind of data you happen to have on
  173. hand for its parameters.  In this case, you can feed it 4 ints, (x and y
  174. source and dest), 2 ints (x and y of the dest, continues from where the
  175. last one left off),  2 pairs, one pair (dest only), or a rectangle.
  176. It makes the library easy to use because you can use the data you have
  177. on hand rather than keeping it in the form the library likes, or having
  178. to convert it.
  179.  
  180. When you draw a line, it will appear in some color or colors, using some
  181. logical operation and some pattern.  All this is in the style structure.
  182. Each viewport has its own style.  In the first example program, the color
  183. of the drawing could have been specified by saying
  184.    v.style.FPen= 7;  // forground pen is white
  185. or somesuch.  There is an FPen (forground pen) and a BPen (background pen).
  186. You can set a 16 bit line pattern.  There are two ways the line pattern
  187. is applied.  In all cases 1's in the pattern are drawn using the FPen.
  188. You have your choice with the 0's.  They can be transparent or drawn using
  189. BPen.  In all cases, a logic operation can also be applied to all pixel
  190. drawn:  REPLACE, AND, OR, or XOR.
  191.  
  192. When drawing a polyline, the line pattern is continuous across the whole
  193. thing.  It does not start over with each segment, like most other libraries
  194. do.  This is a general ability:  the style can be set to preserve line
  195. patterns in progress across multiple calls, so lines connect smoothly.
  196. Patterns are applied to curves too.
  197.  
  198. Another fine touch for using patterns is the "open interval".  Say you
  199. draw from A to B and then from B to C.  Point B is drawn twice.  If you
  200. are using XOR mode, that is bad.  If you are trying to make your line
  201. pattern continuous across the segments, that is bad.  With an open
  202. interval, the second line does not draw from B to C but skipps the first
  203. pixel.  B is not drawn twice.  With diagonal lines and scaled coordinate
  204. systems, this would be nearly impossible to do manually.  But ViewPoint
  205. supports it as a low level primitive, where it belongs.
  206.  
  207. There are other fields in the style for dealing with filled shapes.  A
  208. filled shape can be drawn in a solid color using the FPen.  Or it can use
  209. a fill pattern.  The pattern can be any size, though drivers can impose an
  210. allingment restriction (width must be a multiple of 8, for example).
  211. The fill pattern can take two forms.  A one plane fill pattern is just like
  212. the line pattern in two dimentions.  That is, it uses FPen for the 1's and
  213. your choice of BPen or transparent for the 0's.  Or a fill pattern can be
  214. full color.  In all cases, the logic modes apply.
  215.  
  216. Fill patterns work the same way on all filled shapes-- rectangles, polygons,
  217. ellipses, even flood filling.
  218.  
  219. You might think a rectangle is pretty simple.  But with a rotated or
  220. skewed coordinate system the rectangle can appear diamond shaped.
  221. Naturally it handles all this by itself.  But that is simple.
  222.  
  223. Filled polygons are more interesting.  The viewport class has 6 forms of
  224. the filled_polygon() function.  Paramters can be arrays of ints or
  225. pairs, and a starting point can be specified as 2 ints or a pair or left
  226. out.  Polygons are very difficult to do "right" in raster graphics.
  227. ViewPoint implements correct meshing polygons.  That is, two polygons that
  228. have the same edge in common will mesh together seemlessly.  No pixel is
  229. drawn twice.  Only points that are strictly on the inside of the polygon
  230. are drawn, and a a decision process is used to handle points on the
  231. edges and corners.  This means that a polygon mesh can be drawn to form
  232. complex shapes.  Furthermore, the implementation is fast.  It was timed
  233. reciently as being over 30% faster than BGI's filled polygons, and their's
  234. are "sloppy".
  235.  
  236. But sometimes you don't want meshing polygons.  For a single polygon
  237. sitting out there by itself, it can appear "shaved".  You want it to
  238. round off rather than rounding in.  You don't want the left corner pixel
  239. to be zapped.  So you can also specify polygons with Bresenham edges.
  240. That is, the polygon will exactly fit over a set of ordinary lines drawn
  241. between the same points.
  242.  
  243. There are 21 ways to draw lines, 6 to draw filled polygons.  And that is
  244. just counting the function calls, not the variations in the `mode'
  245. parameter for polys or all the differnet settings in the style.
  246. How many ways can you draw ellipses and ellipse related things?  More than
  247. a few dozen... more like hundreds!
  248.  
  249. You can specify center-radii, specify bounding boxes in several different
  250. ways, and so on.  Then you can draw an arc or the whole thing, where the
  251. arc can be specified in several different ways.  The number of functions
  252. needed was into the double digits at the minimum.
  253.  
  254. So a better way was invented.  The different properties of the rendering
  255. call are specified by individual calls, and several forms of each are
  256. available.  This means that the total number of effective calls is equal
  257. to the product of the numbers of its parts.
  258.  
  259. Here are some examples:
  260.    v.ellipse(center,rad_x,rad_y).draw();  //draw whole ellipse
  261.    v.ellipse(bounding_box).arc(angle1,angle2).draw();  //draw arc
  262.  
  263. Notice that the second line is three functions.  The first call, ellipse(),
  264. could have used several (6) different forms to specify the same shape.
  265. The second call, arc(), could have used 2 different forms or be left
  266. out entirely to draw the whole thing.  And finally, the third call, draw(),
  267. does the rendering of the built-up definition.  Instead of draw() you could
  268. have used filled() or pieslice() or others.  This paragraph touched on
  269. 54 (though only 48 are useful) effective rendering functions.
  270.  
  271. Viewports support flood fills.  As you've probably guessed by now, there
  272. are several ways to do it.  First of all, it uses the fill pattern and
  273. style stuff the same way as any other filled shape.  Even if you are
  274. filling with a pattern and a logical operation that turns into the border
  275. color, or that does nothing, it will not get confused.  Any shape can be
  276. filled properly no matter what modes, colors, or styles are in use.
  277. You can have flood fill search out a border color and stop at the border.
  278. Or you can have it fill over a region of a color and stop when it hits
  279. something that is not that color.  For simpler fills, you can specify the
  280. fast fill mode which does not work with arbitrary shapes but is just
  281. fine for convex shapes and is much faster.  There is also a change_color()
  282. function that will change all pixels of one color inside a specified
  283. rectangle into another color.  This function is extremely fast, and is
  284. great for things like hilighting menu choices.
  285.  
  286. There are move and scroll functions that copy stuff from one place on the
  287. screen to another.  Naturally, there are lots of choices on parameters
  288. and modes.
  289.  
  290. Moving is really a special case of bitmap manipulation-- GET and PUT
  291. functions.  Bitmaps are a major part of the ViewPoint library, and they
  292. even have their own class.  Class pixarray has over three dozen functions
  293. in it.
  294.  
  295. A pixarray holds a bitmap image.  It does its own memory management, and
  296. will use the far heap even in a small model program.  You don't have to
  297. allocate memory for it-- that is automatic.  GETing an image is as simple
  298. as:      pix= v.get(r);
  299. where pix is a pixarray, v is a viewport, and r is a rect.  You can use
  300. different forms for the paramters besides a rect.   This shows that
  301. bitmaps can be used in an expressive way-- they can be used in expressions
  302. as high level objects.
  303.  
  304. The flip side of a get is a put.  Just putting a pixarray at some position
  305. would be too boreing.  Using the logical operations is better.  But
  306. there is even more variety:  you can put just part of a pixarray, and
  307. magnify while putting, or both.
  308.  
  309. Besides a place to hold an image between a get and a put, class pixarray
  310. can be used to manipulate the image.  A simple example is to recolor
  311. it.  You can map one set of colors onto another, or extract individual
  312. colors.  You can query the pixarray for its size and other info, and
  313. read and write individual pixels within it, and even copy parts from
  314. one bitmap to another.  A more exotic function is ortho_transform()
  315. which is really 8 functions rolled into one.  It can mirror, transpose,
  316. and rotate (in 90 degree increments) an image.
  317. There are also functions to load and save pixarrays to disk files.
  318.  
  319. This should give you a general feeling for the concepts the library is
  320. founded on.  But it is just scratching the surface.  There is support
  321. for text that lets you have different kinds of fonts and is very
  322. extendable.  And the mouse!  The "intelligent mouse classes" are deserving
  323. of their own demonstration.  You've never seen anything like it!
  324.  
  325. So check it out!  You can have all this for $220 plus shipping.  It
  326. includes full source code.  Tech support is good.  Updates and bug
  327. fixes are available online.  There is a 60 day satisfaction guarantee.
  328.  
  329. John M. Dlugosz
  330. CIS: 70007,4657
  331.  
  332. Dlugosz Software
  333. PO Box 876506
  334. Plano TX 75086
  335. (214)618-2023
  336.